-
Notifications
You must be signed in to change notification settings - Fork 11
For Kubernetes watch, add tests of backoff and reconnection on failures. Also, when watch response is >= 300, count that as a failure. #205
base: master
Are you sure you want to change the base?
Conversation
|
||
KubernetesReader::KubernetesReader(const Configuration& config, | ||
HealthChecker* health_checker, | ||
std::unique_ptr<Sleeper> sleeper) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we rename sleeper
to be a bit more descriptive? This only seems to be used during retry backoffs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. The sleep functionality is to induce the passage of time, so time-related tool names like "Timer", "Stopwatch", "AlarmClock", etc are usually appropriate. Would it make sense to reuse the existing Timer
class and broaden its interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to rename. What would you like?
test/kubernetes_unittest.cc
Outdated
// will return 404s. | ||
// | ||
// This will cause the updater to backoff 3 times and then give up. | ||
server->SetResponse("/api/v1/nodes?limit=1", "{}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit: this is a constant source of confusion for me. WDYT about moving it to a helper function such as InitHealthyServer(server)
to reduce duplication and make the intent clear for the reader?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. This appears in another PR as well, as I recall...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/Makefile
Outdated
purge: clean | ||
$(RM) init-submodules | ||
(cd .. && git submodule deinit -f $(GTEST_MODULE:../%=%)) | ||
(cd .. && git submodule deinit -f $(GTEST_MODULE:../%=%) && git submodule deinit -f $(GMOCK_MODULE:../%=%)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no GMOCK_MODULE
defined yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we end up deinit
2 paths, you can use single command:
git submodule deinit -f $(GTEST_MODULE:../%=%) ${GMOCK_MODULE:../%=%)}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed.
test/Makefile
Outdated
|
||
init-submodules: | ||
(cd .. && git submodule update --init $(GTEST_MODULE:../%=%)) | ||
(cd .. && git submodule update --init $(GTEST_MODULE:../%=%) && git submodule update --init $(GMOCK_MODULE:../%=%)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed.
// Returns false if newer timestamp not found after 3 seconds (polling | ||
// every 100 millis). | ||
bool WaitForUnhealthyComponents(const HealthChecker& health_checker) { | ||
for (int i = 0; i < 30; i++){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: need space between )
and {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
}; | ||
|
||
// Polls health_checker until it has at least one unhealthy component. | ||
// Returns false if newer timestamp not found after 3 seconds (polling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if using this_thread::sleep_for()
, the comments should be at least 3 seconds (polling every 100 millis at least).
ref: https://en.cppreference.com/w/cpp/thread/sleep_for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
test/kubernetes_unittest.cc
Outdated
// Polls health_checker until it has at least one unhealthy component. | ||
// Returns false if newer timestamp not found after 3 seconds (polling | ||
// every 100 millis). | ||
bool WaitForUnhealthyComponents(const HealthChecker& health_checker) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having the timerange in function name will help reader reasoning - otherwise the reader needs to read through comments or code.
maybe WaitForUnhealthComponentsAtLeast3Seconds
? (If the function name is too long, come up with other names which makes sense...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some preliminary comments...
|
||
KubernetesReader::KubernetesReader(const Configuration& config, | ||
HealthChecker* health_checker, | ||
std::unique_ptr<Sleeper> sleeper) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. The sleep functionality is to induce the passage of time, so time-related tool names like "Timer", "Stopwatch", "AlarmClock", etc are usually appropriate. Would it make sense to reuse the existing Timer
class and broaden its interface?
if (verbose) { | ||
LOG(INFO) << "WatchMaster(" << name << ") completed " << body(response); | ||
} | ||
if (status(response) >= 300) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an unrelated fix not mentioned in the PR description. Mitigations, in order of preference, would be to pull it (and the associated test changes) out into a separate PR, or at least mention it in the description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR description. The fix is intertwined with the new tests, so it's not really possible to pull out into a separate PR.
$(TESTS): $(GTEST_LIB) $(CPP_NETLIB_LIBS) $(YAML_CPP_LIBS) | ||
$(TESTS): $(GTEST_LIB) $(GMOCK_LIB) $(CPP_NETLIB_LIBS) $(YAML_CPP_LIBS) | ||
|
||
# All unittest objects depend on GTEST_LIB. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And GMOCK_LIB
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed.
test/kubernetes_unittest.cc
Outdated
// will return 404s. | ||
// | ||
// This will cause the updater to backoff 3 times and then give up. | ||
server->SetResponse("/api/v1/nodes?limit=1", "{}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1. This appears in another PR as well, as I recall...
// SleepFor() calls are invoked. Each is called twice, once each | ||
// for the nodes & pods watchers. | ||
auto sleeper = std::unique_ptr<MockSleeper>(new MockSleeper()); | ||
EXPECT_CALL(*sleeper, SleepFor(1.5)).Times(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why checking that Sleep
was called with appropriate arguments via a mock is better than faking the passage of time and verifying that certain events happened at certain times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find anyway of faking out std::this_thread::sleep_for(). Got any suggestions?
No description provided.